/******************************************************************************
 * Author:      671643387
 * Created:     2016/9/27
 *****************************************************************************/
var http    = require('http');
var util    = require('util');
var async   = require('async');
var HttpReq = require("../HttpRequest.js");
var BG      = require("../BackGroundID.js");

var ServerIdxBase = 100000;
var roomInfoMap = {};
var roomCreatedMap = {};

exports.createGame = function(player, query, resp, onHandled) {
    var user = player.user;
    var respData = null;
    var round = 4;

    // 扣除玩家房卡
    var cardNeed = 1;

    if (!player.checkResource('card', cardNeed)){
        player.sendMsg(ErrorCodes.ERROR_NO_ENUGHT_CARD, findErrString(ErrorCodes.ERROR_NO_ENUGHT_CARD), "createGame", null );
        onHandled();
        return;
    }

    // 判断玩家是否创建房间
    if (roomCreatedMap.hasOwnProperty(player.uid)) {
        //player.sendMsg(ErrorCodes.ERROR_ALREADY_CREATED_ROOM, findErrString(ErrorCodes.ERROR_ALREADY_CREATED_ROOM), "createGame", null );
        respData = roomCreatedMap[player.uid];
        player.sendMsg(0, "", "createGame", {roomId: respData} );
        onHandled();
        return;
    }

    // 玩家没有创建房间，给玩家创建房间
    async.eachSeries(Object.keys(config.LaomaziServers), function(serverIdx, esCb){
        serverIdx = +serverIdx;
        requestLaomazi(serverIdx, player.uid, {
            'round': round,
        }, 'createGame', function(wResp){
            if (wResp.code == 0) {
                // 房间号加上服务器索引数据
                var roomId = wResp.data.roomId;
                roomId += ServerIdxBase * (serverIdx + 1);
                wResp.data.roomId = roomId;
                // 关联房间号和服务器索引
                roomInfoMap[roomId] = serverIdx;

                respData = wResp.data;
                esCb(1);
            } else {
                if (serverIdx >= (config.LaomaziServers.length - 1)) {
                    esCb(2);
                } else {
                    esCb();
                }
            }
        });
    }, function(err){
        var code = 0;
        var desc = "";
        var tempdata = null;
        if (err == 1) {
            // 标记玩家已经创建了房间
            roomCreatedMap[player.uid] = respData.roomId;
            // 创建房间成功
            tempdata = respData;
        } else {
            // 创建房间失败
            code = ErrorCodes.ERROR_CREATE_ROOM_FAILED;
            desc = findErrString(ErrorCodes.ERROR_CREATE_ROOM_FAILED);
        }
        player.sendMsg(code, desc, "createGame", tempdata );
        onHandled();
    });
};

exports.joinRoom = function(player, query, resp, onHandled) {
    var uid = player.uid;
    var roomId = query.args.roomId;
    var serverIdx = roomInfoMap[roomId];

    if (isNaN(serverIdx)) {
        player.sendMsg(ErrorCodes.ERROR_NO_SUCH_ROOM, findErrString(ErrorCodes.ERROR_NO_SUCH_ROOM), "joinRoom", null);
        onHandled();
        return;
    }

    var tempdata = {
        roomId: roomId - (ServerIdxBase * (serverIdx + 1)),
        laomaziServer: getLaomaziServer(serverIdx)
    };
    player.sendMsg(0, "", "joinRoom", tempdata);
    onHandled();
};

// 解散房间
exports.destroyGame = function (player, query, resp, onHandled) {
    var uid = player.uid;
    var roomId = query.args.roomId;
    var serverIdx = roomInfoMap[roomId];

    if (isNaN(serverIdx)) {
        resp.code = ErrorCodes.ERROR_NO_SUCH_ROOM;
        resp.desc = findErrString(ErrorCodes.ERROR_NO_SUCH_ROOM);
        onHandled();
        return;
    }

    // 计算真实房间号码
    roomId = (roomId - (ServerIdxBase * (serverIdx + 1)));

    requestLaomazi(serverIdx, player.uid, {
        'roomId': roomId,
    }, 'destroyGame', function(wResp){
        resp.code = wResp.code;
        resp.desc = wResp.desc;
        onHandled();
    });
};

// 查询玩家数据
exports.queryUser = function(player, query, resp, onHandled){
    var user = player.user;
    resp.data.player = {
        name: user.info.name,
        headpic: user.info.headpic,
        sex: user.info.sex,
        /*totalgame: user.marks.totalgame,
        wingame: user.marks.wingame,*/
    };
    onHandled();
};

// 玩家加入房间
exports.playerJoinedRoom = function(player, query, resp, onHandled){
    var user = player.user;
    user.marks.room = +query.args.roomId;
    player.markDirty('marks.room');
    player.save();
    onHandled();
};

// 玩家退出房间
exports.playerExitRoom = function(player, query, resp, onHandled){
    delete roomCreatedMap[player.uid];

    var user = player.user;
    user.marks.room = 0;
    player.markDirty('marks.room');
    player.save();
    onHandled();
};

// 房间被销毁
exports.roomDestroyed = function(player, query, resp, onHandled) {
    delete roomCreatedMap[player.uid];

    // 清空玩家房间标记
    async.each(query.args.playerUids, function(playerUid, eCb){
        gPlayerMgr.get(playerUid, null, function(tarPlayer){
            if (tarPlayer) {
                tarPlayer.user.marks.room = 0;
                tarPlayer.markDirty('marks.room');
                tarPlayer.save();
            }
            eCb();
        });
    }, function(err){
        onHandled();
    });
};
// 房间游戏结束
exports.roomFinished = function(player, query, resp, onHandled) {
    var roomId = +query.args.roomId;
    var time = +query.args.time;
    var players = query.args.players;

    var nameScores = {};
    var tarPlayers = [];
    for(var pos in players){
        if(!players.hasOwnProperty(pos)){
            continue;
        }
        var record = players[pos];
        //todo
        HttpReq.requestGameManage(BG.ReqArgs.OUTCOME_API, pos, record.name, {record: record.integral}, function (res) {
            if (res.resultcode == BG.ProtoState.RECORD_SUCCESS) {
                DEBUG(util.format("saveReports , %d, %d", pos, record.name));
            }
        });
    }
    // 保存战绩
    async.each(Object.keys(players), function(targetUid, eCb){
        targetUid = +targetUid;
        gPlayerMgr.get(targetUid, null, function(tarPlayer){
            if (tarPlayer) {
                nameScores[(tarPlayer.user.info.name || tarPlayer.uid)] = players[targetUid];
                tarPlayers.push(tarPlayer);
            } else {
                ERROR('GET USER ' + targetUid + ' FAILED');
            }
            eCb();
        });
    }, function(err){
        var report = {
            roomId: roomId,
            time: time,
            players: nameScores,
        };

        tarPlayers.forEach(function(tPlayer){
            tPlayer.user.marks.room = 0;
            tPlayer.saveReport(report);
        });
        onHandled();
    });
};

exports.addNumberGames = function(player, query, resp, onHandled) {
    var isWin = query.args.isWin;
    player.user.marks.totalgame += 1;
    if(isWin){
        player.user.marks.wingame += 1;
    }
    onHandled();
};
exports.addPlayerStats = function(player, query, resp, onHandled) {
    var ownrKey = query.args.ownrKey;
    var cardNum = query.args.cardNum;
    if(!player) {
        resp.code = -1;
        onHandled();
    }
    // 扣除玩家房卡
    var totalCard = player.addResource(ownrKey, cardNum);
    cardNum = Math.abs(cardNum);
    if(totalCard) {
        player.save();
        HttpReq.requestGameManage(BG.ReqArgs.ROOM_API, player.uid, player.user.info.name, {card: cardNum}, function (res) {
            if (res.resultcode == BG.ProtoState.CARD_NORMAL) {
                DEBUG(util.format("decCards , %d, %d", player.uid, cardNum));
            }
        });
        var tempData = {
            totalCard: totalCard,
        };
        player.sendMsg(0, "", "roomCardStatus", tempData);
        onHandled();
    }else {
        player.sendMsg(-1, "change roomCard error", "roomCardStatus", null);
        onHandled();
    }
};
///////////////////////////////////////////////////////////////////////////////

/**
 * 请求扑克服务器
 * @param uid
 * @param args
 * @param act
 * @param callback
 */
function requestLaomazi(serverIdx, uid, args, act, callback) {
    var serverConf = config.LaomaziServers[serverIdx];

    var options = {
        host: serverConf.host,
        port: serverConf.port,
        path: '/',
        method: 'POST'
    };

    var resp = {
        code: 0,
        desc: '',
        data: {},
    };
    var req = http.request(options, function(res) {
        var chunks = [];
        res.on('data', function(chunk) {
            chunks.push(chunk);
        });

        res.on('end', function() {
            var data = Buffer.concat(chunks).toString();
            var cloudResp = null;
            try {
                cloudResp = JSON.parse(data);
            } catch (error) {
                ERROR('laomazi resp ' + data);
                cloudResp = null;
            }

            if (!cloudResp) {
                resp.code = ErrorCodes.ERROR_REQ_SERVICE_FAILED;
                resp.desc = findErrString(ErrorCodes.ERROR_REQ_SERVICE_FAILED);
            } else {
                resp.code = cloudResp.code;
                resp.desc = cloudResp.desc;
                resp.data = cloudResp.data;
            }

            callback && callback(resp);
        });
    });

    req.on('error', function(err) {
        resp.code = ErrorCodes.ERROR_REQ_SERVICE_FAILED;
        resp.desc = findErrString(ErrorCodes.ERROR_REQ_SERVICE_FAILED);
        callback && callback(resp);
    });

    req.end(util.format('mod=api&act=%s&uid=%d&args=%s', act,
        uid, JSON.stringify(args)));
    req.end();
}

function getLaomaziServer(serverIdx) {
    var serverConf = config.LaomaziServers[serverIdx];
    return util.format('http://%s:%s/', serverConf.host, serverConf.port);
};

function getUniquePlayerKey(serverIdx, uid) {
    var serverConf = config.LaomaziServers[serverIdx];
    return serverConf.port + '.' + serverConf.host + '.' + uid;
}

exports.doTick = function() {
    var statusInfos = {};
    async.eachSeries(Object.keys(config.LaomaziServers), function(serverIdx, esCb){
        serverIdx = +serverIdx;
        requestLaomazi(serverIdx, 10001, {
        }, 'status', function(wResp){
            if (wResp.code == 0) {
                statusInfos[serverIdx] = {
                    'totalRoom': wResp.data.totalRoom,
                };
            } else {
                ERROR('STATUS SERVER ' + serverIdx + ' FAILED: ' + wResp.desc);
            }
            esCb();
        });
    }, function(err){
        for (var key in statusInfos) {
            if (!statusInfos.hasOwnProperty(key)) {
                continue;
            }

            var svrInfo = statusInfos[key];
            LOG('MAHJONG SERVER [' + (+key) + '] HAS ' + svrInfo.totalRoom + ' ROOM');
        }
    });
};